package model

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"time"
)

// 获取 access_token 的结构体
type AccessTokenRequest struct {
	AppID     string `json:"appid"`
	GrantType string `json:"grant_type"`
	Secret    string `json:"secret"`
}

// 返回的 access_token 结构体
type AccessTokenResponse struct {
	Data    map[string]interface{} `json:"data"`
	ErrNo   int                    `json:"err_no"`
	ErrTips string                 `json:"err_tips"`
}

// 获取 access_token 的函数
func getAccessToken(appID, secret string) (string, error) {
	// 构造请求体
	request := AccessTokenRequest{
		AppID:     appID,
		GrantType: "client_credential",
		Secret:    secret,
	}

	// 将请求体序列化为 JSON
	body, err := json.Marshal(request)
	if err != nil {
		return "", fmt.Errorf("failed to marshal request body: %v", err)
	}

	// 构造 HTTP 请求
	url := "https://minigame.zijieapi.com/mgplatform/api/apps/v2/token"
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(body))
	if err != nil {
		return "", fmt.Errorf("failed to create request: %v", err)
	}

	// 设置请求头
	req.Header.Set("Content-Type", "application/json")

	// 发送请求
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("failed to send request: %v", err)
	}
	defer resp.Body.Close()

	// 读取响应体
	body, err = io.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("failed to read response body: %v", err)
	}

	// 解析响应体
	var response AccessTokenResponse
	if err := json.Unmarshal(body, &response); err != nil {
		return "", fmt.Errorf("failed to unmarshal response body: %v", err)
	}

	// 检查错误码
	if response.ErrNo != 0 {
		return "", fmt.Errorf("failed to get access_token: %s", response.ErrTips)
	}

	// 使用类型断言并处理错误
	str, ok := response.Data["access_token"].(string)
	if !ok {
		str = ""
	}
	return str, nil
}

// 定时更新 access_token
func refreshToken(appID, secret string) {
	// 获取新的 access_token
	token, err := getAccessToken(appID, secret)
	if err != nil {
		log.Printf("Error refreshing access_token: %v\n", err)
	}

	// 更新全局变量
	globalAccessToken.Store(appID, token)
	log.Println(appID, "Access token refreshed:", token)

	ticker := time.NewTicker(1 * time.Hour) // 每小时更新一次
	defer ticker.Stop()
	
	for {
		select {
		case <-ticker.C:
			// 获取新的 access_token
			token, err := getAccessToken(appID, secret)
			if err != nil {
				fmt.Printf("Error refreshing access_token: %v\n", err)
				continue
			}

			// 更新全局变量
			globalAccessToken.Store(appID, token)
			log.Println(appID, "Access token refreshed:", token)
		}
	}
}
